#include "RegExFilter.h"
#include "Tree.h"

using namespace std;

RegExFilter::RegExFilter(const string & regEx)
{
	InvalidFilterInfo error;

	const char * errStr;
	int errOffset;
	int errCode;
	compiled = pcre_compile2(
		regEx.c_str(),
		0,
		&errCode,
		&errStr,
		&errOffset,
		NULL);
	if ( compiled == NULL )
	{
		error.errorCode = errCode;
		error.errorPosition = errOffset;
		error.errorMsg = errStr;
		throw error;
	}
	studied = pcre_study(
		compiled,
		0,
		&errStr);
	if ( errStr != NULL )
	{
		error.errorCode = -1;
		error.errorPosition = -1;
		error.errorMsg = errStr;
		throw error;
	}
}

RegExFilter::~RegExFilter()
{
	pcre_free(studied);
	pcre_free(compiled);
}

bool RegExFilter::Match(const Tree & tree) const
{
	vector< Tree::Node * >::const_iterator it = tree.m_roots.begin();
	while ( it != tree.m_roots.end() )
	{
		if ( Match( **it ) )
			return true;
		it++;
	}
	return false;
}

bool RegExFilter::Match(const Tree::Node & node) const
{
	bool result;
	int ovector[32];
	int rc = pcre_exec( compiled, studied, node.GetCaption().c_str(), (int)node.GetCaption().length(), 0, 0, ovector, 32);
	result = ( rc >= 0 );
	if (result)
		return result;
	for (size_t i = 0; i < node.m_children.size(); i++)
	{
		result = result || Match(*node.m_children[i]);
		if (result)
			return result;
	}
	return result;
}